package com.tianji.learning.service.impl;

import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.client.course.CatalogueClient;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.dto.course.CataSimpleInfoDTO;
import com.tianji.api.dto.course.CourseFullInfoDTO;
import com.tianji.api.dto.course.CourseSimpleInfoDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.domain.query.PageQuery;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.ObjectUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.entity.LearningLesson;
import com.tianji.learning.enums.LessonStatus;
import com.tianji.learning.mapper.LearningLessonMapper;
import com.tianji.learning.service.ILearningLessonService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.learning.vo.LearningLessonVO;
import lombok.Builder;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 学生课程表 服务实现类
 * </p>
 *
 * @author tj-learning
 * @since 2023-05-25
 */
@RequiredArgsConstructor
@Service
public class LearningLessonServiceImpl extends ServiceImpl<LearningLessonMapper, LearningLesson> implements ILearningLessonService {
    private final CourseClient courseClient;
    private final CatalogueClient catalogueClient;

    @Transactional
    @Override
    public void addUserLessons(Long userId, List<Long> courseIds) {
        // 1.查询课程有效期
        List<CourseSimpleInfoDTO> cInfoList = courseClient.getSimpleInfoList(courseIds);
        if (CollUtils.isEmpty(cInfoList)) {
            log.error("课程信息不存在，无法添加到课表");
            return;
        }
        // 2.循环遍历，处理LearingLesson数据
        List<LearningLesson> list = new ArrayList<>(cInfoList.size());
        for (CourseSimpleInfoDTO cInfo : cInfoList) {
            // 获取过期时间
            Integer validDuration = cInfo.getValidDuration();
            // 填充用户id和课程id
            LearningLesson lesson = LearningLesson.builder()
                    .courseId(cInfo.getId()) // 设置课程id
                    .userId(userId) // 设置用户id
                    .build();// 设置过期时间
            // 判断validDuration是否合法
            if (validDuration != null && validDuration > 0) {
                LocalDateTime now = LocalDateTime.now();
                lesson.setCreateTime(now);
                lesson.setExpireTime(now.plusMonths(validDuration));
            }
            // 存入list集合
            list.add(lesson);
        }
        // 3.批量新增
        this.saveBatch(list);
    }

    @Override
    public PageDTO pageQuery(PageQuery pageQuery) {
        // 获取当前登录用户
        Long userId = UserContext.getUser();
        // 根据用户id，分页查询课程
        Page<LearningLesson> page = this.lambdaQuery().eq(LearningLesson::getUserId, userId)
                .page(pageQuery.toMpPage("latest_learn_time", false));
        List<LearningLesson> records = page.getRecords();// 获取当前页数据
        if (CollUtils.isEmpty(records)) {
            return PageDTO.empty(page);
        }
        // 查询课程信息
        Map<Long, CourseSimpleInfoDTO> map = this.queryCourseSimpleInfoList(records);

        // 封装VO返回
        List<LearningLessonVO> list = new ArrayList<>(records.size());
        // 循环遍历，把LearningLesson转为VO
        for (LearningLesson record : records) {
            // 拷贝基础属性
            LearningLessonVO lessonVO = BeanUtils.copyBean(record, LearningLessonVO.class);
            // 获取课程信息，填充到VO
            CourseSimpleInfoDTO cInfo = map.get(record.getCourseId());
            lessonVO.setCourseName(cInfo.getName());
            lessonVO.setCourseCoverUrl(cInfo.getCoverUrl());
            lessonVO.setSections(cInfo.getSectionNum());
            list.add(lessonVO);
        }

        return PageDTO.of(page, list);
    }

    @Override
    public LearningLessonVO queryMyCurrentLesson() {
        // 获取当前登录用户id
        Long userId = UserContext.getUser();
        // 获取正在学习的课程
        LearningLesson lesson = this.lambdaQuery()
                .eq(LearningLesson::getUserId, userId)
                .eq(LearningLesson::getStatus, LessonStatus.LEARNING.getValue())
                .orderByDesc(LearningLesson::getLatestLearnTime)
                .last("limit 1")
                .one();
        if (ObjectUtils.isEmpty(lesson)) {
            return null;
        }
        // 属性拷贝 po -> vo
        LearningLessonVO lessonVO = BeanUtils.copyBean(lesson, LearningLessonVO.class);
        // 查询课程信息
        CourseFullInfoDTO cInfo = courseClient.getCourseInfoById(lesson.getCourseId(), false, false);
        if (ObjectUtils.isEmpty(cInfo)) {
            throw new BadRequestException("课程信息不存在！");
        }
        lessonVO.setCourseCoverUrl(cInfo.getCoverUrl());
        lessonVO.setSections(cInfo.getSectionNum());
        lessonVO.setCourseName(cInfo.getName());
        // 获取课程总数
        Integer count = this.lambdaQuery()
                .eq(LearningLesson::getUserId, userId)
                .count();
        lessonVO.setCourseAmount(count);
        // 查询小节信息
        List<CataSimpleInfoDTO> cataInfos =
                catalogueClient.batchQueryCatalogue(CollUtils.singletonList(lesson.getLatestSectionId()));
        if (!CollUtils.isEmpty(cataInfos)) {
            CataSimpleInfoDTO cataInfo = cataInfos.get(0);
            lessonVO.setLatestSectionName(cataInfo.getName());
            lessonVO.setLatestSectionIndex(cataInfo.getCIndex());
        }

        return lessonVO;
    }

    @Override
    public void deleteUserLesson(Long userId, List<Long> courseIds) {
        // 查询课程是否在有效期内 或处于 已完成状态
        LearningLesson lesson = this.lambdaQuery()
                .select(LearningLesson::getStatus, LearningLesson::getId)
                .in(LearningLesson::getCourseId, courseIds)
                .in(LearningLesson::getStatus, LessonStatus.EXPIRED, LessonStatus.FINISHED)
                .eq(LearningLesson::getUserId, userId)
                .one();

        if (ObjectUtils.isEmpty(lesson)) {
            throw new BadRequestException("课程还在有效期，无法删除");
        }
        // 符合条件，直接删除
        this.removeById(lesson.getId());
    }

    @Override
    public Long isLessonValid(Long courseId) {
        LearningLesson lesson = this.lambdaQuery()
                .eq(LearningLesson::getUserId, UserContext.getUser())
                .eq(LearningLesson::getCourseId, courseId)
                .one();
        if (ObjectUtils.isEmpty(lesson)){
            return null;
        }
        if (lesson.getStatus() == LessonStatus.EXPIRED.getValue()){
            return null;
        }
        return lesson.getId();
    }

    private Map<Long, CourseSimpleInfoDTO> queryCourseSimpleInfoList(List<LearningLesson> records) {
        // 获取课程id
        Set<Long> cIds = records.stream().map(LearningLesson::getCourseId).collect(Collectors.toSet());
        // 查询课程信息
        List<CourseSimpleInfoDTO> cInfoList = courseClient.getSimpleInfoList(cIds);
        if (CollUtils.isEmpty(cInfoList)) {
            // 课程不存在，不允许添加
            throw new BadRequestException("课程信息不存在！");
        }
        // 处理数据，封装成map集合，key是courseId，value是course本身
        Map<Long, CourseSimpleInfoDTO> cMap = cInfoList.stream().collect(Collectors.toMap(CourseSimpleInfoDTO::getId, c -> c));
        return cMap;
    }
}
